﻿// Copyright 2013 Ronald Schlenker, www.technewlogic.de.
// 
// This file is part of Byond.
// 
// Byond is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
// 
// Byond is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Byond.  If not, see <http://www.gnu.org/licenses/>.

using System;

namespace Byond
{
	class FieldAndPropWrapper
	{
		// TODO: FastReflection nutzen

		public FieldAndPropWrapper(
			string memberName,
			Type memberType,
			bool persist,
			Func<int?, object> getValueMethod,
			Action<object, int?> setValueMethod)
		{
			MemberName = memberName;
			MemberType = memberType;
			Persist = persist;
			GetValueMethod = getValueMethod;
			SetValueMethod = setValueMethod;

			// Validate
			if (typeof(Delegate).IsAssignableFrom(MemberType.BaseType) && !IsAction)
				throw new Exception(string.Format("Cannot bind the member {0} of type {1}. Type must be Action or Action<T>.", memberName, memberType));
		}

		public string MemberName { get; private set; }
		public Type MemberType { get; private set; }
		public bool Persist { get; private set; }
		public Func<int?, object> GetValueMethod { get; private set; }
		public Action<object, int?> SetValueMethod { get; private set; }

		public bool IsAction
		{
			get { return IsParamlessAction || IsParamAction; }
		}

		public bool IsParamlessAction
		{
			get
			{
				return MemberType.IsGenericType &&
					MemberType.GetGenericTypeDefinition() == typeof(Action<>);
			}
		}

		public bool IsParamAction
		{
			get { return MemberType == typeof(Action); }
		}

		public bool BindingMatches(string bindingExpression)
		{
			int? index;
			string bindingExpressionNameWithoutIndex;
			return bindingExpression.TryGetBindingIndex(out index, out bindingExpressionNameWithoutIndex)
				? MemberName == bindingExpressionNameWithoutIndex
				: MemberName == bindingExpression;
		}
	}
}